With software companies competing to beat one another to market with the “latest and greatest” software products and technologies, the need for reduced development cycle times is very high. Developers usually perform numerous iterations of code development, modification, deployment and testing of a design before the product can be shipped. It is often useful for the software developer to view and test the results of each incremental software change as it is completed before proceeding to the next change. However, in many software development environments, the process of rebuilding, redeploying and testing complex software projects can be tedious and time consuming. This is especially true when building large web applications that must be packaged and deployed to a server before they can be tested. For example consider the Java 2 Enterprise Edition application model depicted in FIG. 1. When a large number of iterations is required, the accumulated build and deploy time becomes significant. The resulting delays are undesirable in a market where short development times are necessary in order to remain competitive.
Deploying complex software applications involves more than just placing the files on the server. Each component and application must be configured to e.g. allocate appropriate server resources and specify security requirements. To satisfy these requirements, enterprise application servers require the creation of several deployment descriptors. These descriptors are specially formatted files that describe each of the components being deployed, their relationships, their required resources and other characteristics such as security requirements. An example of one of these deployment descriptors is shown below.
<Domain Name=“workshop”> <SNMPAgent Name=“workshop”/> <ApplicationManager Name=“workshop”/> <JTA Name=“workshop” TimeoutSeconds=“500”/> <Log FileName=“./wl-domain.log” Name=“workshop”/> <Server  AcceptBacklog=“50”  AdministrationPort=“1”  ClusterWeight=“1”   ConsoleInputEnabled=“false” DGCIdlePeriodsUntilTimeout=“2”   DefaultProtocol=“t3” DefaultSecureProtocol=“t3s”   HttpdEnabled=“true” ListenPort=“7001” Name=“cgServer”   NativeIOEnabled=“true” ServerVersion=“7.0.0.0”   SocketReaderTimeoutMaxMillis=“10”   ReliableDeliveryPolicy=“RMDefaultPolicy”   TransactionLogFilePrefix=“./logs/”   TunnelingClientPingSecs=“45” TunnelingClientTimeoutSecs=“40”>   <COM Name=“cgServer”/>   <ExecuteQueue Name=“default” ThreadCount=“15”/>   <JTAMigratableTarget Cluster=“”     Name=“cgServer”     UserPreferredServer=“cgServer”/>   <KernelDebug Name=“cgServer”/>   <KernelDebug Name=“workshop”/>   <SSL Enabled=“true” IdentityAndTrustLocations=“KeyStores”    ListenPort=“7002” Name=“cgServer”/>   <ServerDebug Name=“cgServer”/>   <ServerStart Name=“cgServer”/>   <WebServer     DefaultWebApp=“default”     LogFileName=“./logs/access.log” LoggingEnabled=“true”     Name=“cgServer”/> </Server> <JMSFileStore Directory=“rmfilestore” Name=“FileStore”/> <WSReliableDeliveryPolicy Name=“RMDefaultPolicy” Store=“FileStore”   DefaultRetryCount=“10” DefaultTimeToLive=“60000”/> <JDBCConnectionPool CapacityIncrement=“1”   DriverName=“com.pointbase.jdbc.jdbcUniversalDriver”   InitialCapacity=“5” MaxCapacity=“20” Name=“cgPool”   Properties=“user=cajun;password=abc”   RefreshMinutes=“0” ShrinkPeriodMinutes=“15”   ShrinkingEnabled=“true”   Targets=“cgServer” TestConnectionsOnRelease=“false”   SupportsLocalTransaction=“true”   TestConnectionsOnReserve=“false”   URL=“jdbc:pointbase server://localhost:9093/cajun”/> <JDBCTxDataSource   Name=“cgDataSource”   JNDIName=“cgDataSource”   PoolName=“cgPool”   EnableTwoPhaseCommit=“true”   Targets=“cgServer”/> <Application Deployed=“true” Name=“JWSQueueTransport”       Path=“c:/bea2/weblogic81/server/lib/”       TwoPhase=“false”>   <EJBComponent Name=“QueueTransportEJB” Targets=“cgServer”          URI=“QueueTransportEJB.jar”/> </Application> <JMSJDBCStore   ConnectionPool=“cgPool” Name=“cgJMSStore”   PrefixName= “cajun” /> <JMSConnectionFactoryJNDIName=“weblogic.jws.jms.QueueConnectionFactory”   Name=“cgQueue” Targets=“cgServer” UserTransactionsEnabled=“true”   Notes=“User transactions must be enabled to ensure transactioncoordination for persistence and asynchronous operations”/> <JDBCTxDataSource   Name=“cgSampleDataSource”   JNDIName=“cgSampleDataSource”   PoolName=“cgPool”   EnableTwoPhaseCommit=“true”   Targets=“cgServer”/> <Application Deployed=“true” Name=“certificate” Path=“./”TwoPhase =“false”>   <WebAppComponent Name=“certificate” Targets=“cgServer”                URI=“certificate.war”/>   </Application>   <Application Deployed=“true” Name=“default”         Path=“./wlw_apps/DefaultWebAppEar”>   <WebAppComponent Name=“default” ServletReloadCheckSecs=“0”             Targets=“cgServer” URI=“DefaultWebApp”/> </Application> <Application Name=“samples” Path=“./wlw_apps/samplesEar”   StagingMode=“nostage” TwoPhase=“true”>   <WebAppComponent Name=“BusinessControls” Targets=“cgServer”             URI=“BusinessControls”/>   <WebAppComponent Name=“samples” Targets=“cgServer” URI=“samples”/> </Application> <JMSServer Name=“cgJMSServer” Store=“cgJMSStore”       Targets=“cgServer”>   <JMSQueue JNDIName=“credit.response”         Name=“credit.response”         RedeliveryLimit=“2” StoreEnabled=“default”/>   <JMSQueue JNDIName=“jms.SimpleJmsQ”         Name=“jms.SimpleJmsQ”         RedeliveryLimit=“2” StoreEnabled=“default”/>   <JMSQueue JNDIName=“jms.CustomJmsCtlQ”         Name=“jms.CustomJmsCtlQ”         RedeliveryLimit=“2” StoreEnabled=“default”/>   <JMSQueue JNDIName=“tutorial.credit.request”         Name=“tutorial.credit.request”         RedeliveryLimit=“2” StoreEnabled=“default”/>   <JMSQueue JNDIName=“credit.request”         Name=“credit.request”         RedeliveryLimit=“2” StoreEnabled=“default”/>   <JMSQueue JNDIName=“jws.queue”         Name=“cgJWSQueue”         RedeliveryLimit=“2” StoreEnabled=“default”/>   <JMSTopic JNDIName=“jms.AccountUpdate”         Name=“jms.AccountUpdate”         RedeliveryLimit=“2” StoreEnabled=“default”/> </JMSServer></Domain>
Developing these deployment descriptors manually is tedious and time consuming. In addition, each time the deployment configuration changes, the deployment descriptors must change to match. This process can complicate development tasks and lengthen development cycles.